package 基本线程机制.新类库中的构件;

import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/*在上面的例子里，栅栏初始计数为5，说明需要5个线程达到栅栏，这5个线程才能继续执行。当在一个线程里，调用barrier.await相当于告诉栅栏，已经有一个线程达到栅栏。
 当barrier.await执行5次后，栅栏打开，所有5个线程都可以继续执行。此时，还会发生两件事，栅栏会执行栅栏动作，也就是在初始化栅栏对象时产生的Runnable类对象需要执行的run方法，还有一件事，栅栏的计数会重置为5。
综合以上，栅栏和闭锁有以下区别
栅栏可重复使用，在计数器为0的时候，会重置为原来的计数
栅栏有栅栏动作，在计数器为0的时候，会执行栅栏动作*/
public class CyclicBarrierDemo {  
    public static void main(String[] args) {  
        CyclicBarrier barrier = new CyclicBarrier(5, new Runnable() {  
            //栅栏动作，在计数器为0的时候执行  
            @Override  
            public void run() {  
                System.out.println("我们都准备好了.");  
            }  
        });  
          
        ExecutorService es = Executors.newCachedThreadPool();  
        for (int i = 0; i < 5; i++) {  
            es.execute(new Roommate(barrier));  
        }  
    }  
}  
  
class Roommate implements Runnable {  
    private CyclicBarrier barrier;  
    private static int Count = 1;  
    private int id;  
  
    public Roommate(CyclicBarrier barrier) {  
        this.barrier = barrier;  
        this.id = Count++;  
    }  
  
    @Override  
    public void run() {  
        System.out.println(id + " : 我到了");  
        try {  
            //通知barrier，已经完成动作，在等待  
            barrier.await();  
            System.out.println("Id " + id + " : 点菜吧!");  
        } catch (InterruptedException e) {  
            e.printStackTrace();  
        } catch (BrokenBarrierException e) {  
            e.printStackTrace();  
        }  
    }  
}  